package profile;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.beans.PropertyChangeEvent;

import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;

import view.IView;
import controller.ProfileController;

/**
 * This is the main profile result frame that shows the graph of 
 * a profile, along with some statistics and the threshold selection
 * on the side.  
 * 
 */
public class ProfileResultFrame extends JFrame implements IView {

    private static final long serialVersionUID = 965634871039425317L;
    
    private Profile profile;
    private ChartPanel profilePanel;
    private String chartTitle;
    private int currentMad = 3;
    
    /**
     * I initially set this up to use a JLayeredPane because I was going to 
     * add a "crop box" for cropping the profile.  I've since switched the crop
     * implementation to share code with low pass filter, so the JLayeredPane
     * is no longer necessary.  I'm leaving it in place since it works and
     * makes adding functionality in the future easier.
     */
    private JLayeredPane layeredPane = new JLayeredPane();
    private JPanel leftPanel = new JPanel();
    private JFreeChart profileChart;
    
    public ProfileResultFrame(Profile profile, String chartTitle) {
        super(chartTitle);
        this.profile = profile;
        this.chartTitle = chartTitle;
        
        profile.getController().addView(this);
        profile.getController().addModel(profile.getModel());
        
        initComponents();
        
        this.setSize(new Dimension(1024, 600));
    }
    
    /**
     * Opens the frame at location (x,y)
     * 
     * @param x
     * @param y
     */
    public void openFrame(int x, int y) {
        setLocation(x, y);
        setVisible(true);
    }
    
    public void openFrame(String title, int x, int y) {
        setLocation(x, y);
        setVisible(true);
    }

    private void initComponents() {
        initLeftPanel();
        
        this.setLayout(new BorderLayout());
        this.add(leftPanel, BorderLayout.WEST);
        this.add(layeredPane, BorderLayout.CENTER);
        initLayeredPane();
        
        updateProfilePanel();
    }
    
    private void initLeftPanel() {
        leftPanel.add(new ProfileResultLeftPanel(profile, currentMad, this));
    }
    
    private void initLayeredPane() {
        //add a ComponentListener so the layered pane responds to componentResized
        layeredPane.addComponentListener(new ComponentListener() {

            @Override
            public void componentHidden(ComponentEvent ce) { }

            @Override
            public void componentMoved(ComponentEvent ce) { }

            @Override
            public void componentResized(ComponentEvent ce) {
                Component c = ce.getComponent();
                int width = c.getWidth();
                int height = c.getHeight();
                if (profilePanel != null) {
                    profilePanel.setBounds(0, 0, width, height);
                }
            }

            @Override
            public void componentShown(ComponentEvent ce) { }
            
        });
        
    }
    
    @Override
    public void modelPropertyChange(PropertyChangeEvent evt) {
        if(evt.getPropertyName().equals(ProfileController.PROFILE_MAD_PROPERTY)) {
            currentMad = (Integer) evt.getNewValue();
            updateProfilePanel();
        }
    }

    /**
     * Adds the chart to the main profilePanel or updates it if it already exists
     */
    protected void updateProfilePanel() {
        if(profilePanel != null) {
            layeredPane.remove(profilePanel);
        }
        
        profileChart = ProfileChartHelper.getProfileChart(profile, chartTitle, currentMad, true);
        //default width and height of 800x600, but if the user resizes the window we want to get
        //the current width and height when we re-add the panel
        int panelWidth = 800; int panelHeight = 600;
        if(profilePanel != null) {
            panelWidth = layeredPane.getWidth();
            panelHeight = layeredPane.getHeight();
        }
        profilePanel = new ProfileChartPanel(profileChart, profile.getController(), panelWidth, panelHeight);
        profilePanel.setBounds(0, 0, panelWidth, panelHeight);
        layeredPane.setBounds(leftPanel.getWidth(), 0, panelWidth, panelHeight);
        layeredPane.add(profilePanel, JLayeredPane.DEFAULT_LAYER);
        layeredPane.repaint();
    }
    
    public JFreeChart getProfileChart() {
        return profileChart;
    }
    
    

}
